package com.ztgf.sys.service;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.db.utils.RedisUtil;
import com.ztgf.shopping.models.dto.shop.ShopInvoiceHeadDTO;
import com.ztgf.shopping.models.dto.shop.ShopSysInvoiceDTO;
import com.ztgf.shopping.models.service.shop.IShopInvoiceHeadService;
import com.ztgf.shopping.models.service.shop.IShopSysInvoiceService;
import com.ztgf.shopping.models.vo.shop.ShopSysInvoiceVO;
import com.ztgf.sms.models.bo.EmailSendBO;
import com.ztgf.sms.models.service.IEmailInfoService;
import com.ztgf.sys.common.config.YmlConfig;
import com.ztgf.sys.mapper.SysInvoiceMapper;
import com.ztgf.sys.models.bo.SysInvoiceBO;
import com.ztgf.sys.models.bo.SysInvoiceQueryBO;
import com.ztgf.sys.models.bo.SysInvoiceSaveBO;
import com.ztgf.sys.models.constant.SysConstant;
import com.ztgf.sys.models.dto.SysInvoiceDTO;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.service.ISysInvoiceService;
import com.ztgf.sys.models.vo.SysInvoiceVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 平台开票控制器
 *
 * @author liyang
 * @Date 2021-05-26 11:50:38
 */
@DubboService
@Slf4j
public class SysInvoiceServiceImpl extends ServiceImpl<SysInvoiceMapper, SysInvoiceDTO> implements ISysInvoiceService{

    @Resource
    private YmlConfig ymlConfig;

    @DubboReference
    private IShopInvoiceHeadService shopInvoiceHeadService;
    @DubboReference
    private IShopSysInvoiceService shopSysInvoiceService;
    @DubboReference
    private IEmailInfoService emailInfoService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean add(SysInvoiceSaveBO saveBO) {
        SysInvoiceDTO dto = new SysInvoiceDTO();
        BeanUtils.copyProperties(saveBO,dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        return this.insert(dto);
    }

    /**
     * 店铺申请开票
     * @param bo
     * @return
     */
    @Override
    public boolean saveInvoice(SysInvoiceBO bo) {
        SysInvoiceDTO sysInvoiceDTO = new SysInvoiceDTO ();
        sysInvoiceDTO.setId (ymlConfig.getPkId ()); //主键
        sysInvoiceDTO.setCreateUserId (bo.getShopId ()); //店铺id
        sysInvoiceDTO.setShopId (bo.getShopId ()); //店铺id
        sysInvoiceDTO.setStatus (0); //发票状态 0申请开票中，1开票成功
//        sysInvoiceDTO.setType (bo.getType ()); //类型 0纸质发票，1电子发票
        sysInvoiceDTO.setInvoiceType (bo.getInvoiceType ()); //发票类型 1普票，0专票
        sysInvoiceDTO.setPriceType (bo.getPriceType ()); //发票类型 0物流费，1技术服务费
        sysInvoiceDTO.setReceivingName (bo.getReceivingName ()); //收票人姓名
        sysInvoiceDTO.setMobile (bo.getMobile ()); //收票人手机号
        sysInvoiceDTO.setEmail (bo.getEmail ()); //接收电子发票邮箱
        sysInvoiceDTO.setReceivingAddress (bo.getReceivingAddress ()); //收票人地址
        sysInvoiceDTO.setAreaId(bo.getAreaId());
        sysInvoiceDTO.setInvoiceContent (bo.getInvoiceContent ()); //发票货物或应税劳务名称
        sysInvoiceDTO.setPrice (bo.getInvoicePrice ()); //单价
        sysInvoiceDTO.setInvoicePrice (bo.getInvoicePrice ());//发票金额
        sysInvoiceDTO.setInvoiceIds (bo.getInvoiceIds ());
        sysInvoiceDTO.setSellOrBuyType (bo.getSellOrBuyType ());
        if (bo.getInvoiceType () == 1){ //普票
            sysInvoiceDTO.setTaxRate (SysConstant.COMMON_TAX_RATE);
        }
        if (bo.getInvoiceType () == 0){ //专票
            sysInvoiceDTO.setTaxRate (SysConstant.COMMON_TAX_RATE);
        }
        BigDecimal  taxRate = BigDecimal.valueOf(sysInvoiceDTO.getTaxRate ()).divide(BigDecimal.valueOf(100));
        sysInvoiceDTO.setTaxRatePrice (sysInvoiceDTO.getInvoicePrice ().multiply (taxRate)); //税额
        sysInvoiceDTO.setRemarks (bo.getRemarks ()); //备注

        ShopInvoiceHeadDTO shopInvoiceHeadDTO = shopInvoiceHeadService.selectById (bo.getInvoiceHeaderId ()); //获取店铺发票信息
        sysInvoiceDTO.setInvoiceCompanyName (shopInvoiceHeadDTO.getName ());
        sysInvoiceDTO.setTaxpayerId (shopInvoiceHeadDTO.getTaxpayerId ());
        sysInvoiceDTO.setCompanyAdress (shopInvoiceHeadDTO.getCompanyAdress ());
        sysInvoiceDTO.setCompanyPhone (shopInvoiceHeadDTO.getCompanyPhone ());
        sysInvoiceDTO.setBankAddress (shopInvoiceHeadDTO.getBankAddress ());
        sysInvoiceDTO.setBankCardNo (shopInvoiceHeadDTO.getBankCardNo ());

        ShopInvoiceHeadDTO adminHeadDTO = shopInvoiceHeadService.selectByType (); //获取admin发票信息
        sysInvoiceDTO.setAdminInvoiceCompanyName (adminHeadDTO.getName ());
        sysInvoiceDTO.setAdminTaxpayerId (adminHeadDTO.getTaxpayerId ());
        sysInvoiceDTO.setAdminCompanyAdress (adminHeadDTO.getCompanyAdress ());
        sysInvoiceDTO.setAdminCompanyPhone (adminHeadDTO.getCompanyPhone ());
        sysInvoiceDTO.setAdminBankAddress (adminHeadDTO.getBankAddress ());
        sysInvoiceDTO.setAdminBankCardNo (adminHeadDTO.getBankCardNo ());

        boolean saveFlag = this.insert (sysInvoiceDTO);
        boolean updateFlag = false;
        if(saveFlag){
            //按明细开票
            if (StringUtils.isNotBlank(bo.getInvoiceIds ())){
                List<ShopSysInvoiceDTO> shopSysInvoiceDTOS = new ArrayList<>();
                String[] split = bo.getInvoiceIds ().split (",");
                for (String id :split) {
                    ShopSysInvoiceDTO shopSysInvoiceDTO = new ShopSysInvoiceDTO ();
                    shopSysInvoiceDTO.setId (Long.parseLong (id));
                    shopSysInvoiceDTO.setSysInvoiceId (sysInvoiceDTO.getId ()); //平台开票表id
                    shopSysInvoiceDTO.setStatus (0); //开票状态 0已开票，1未开票
                    shopSysInvoiceDTOS.add (shopSysInvoiceDTO);
                }
                updateFlag = shopSysInvoiceService.updateBatchById (shopSysInvoiceDTOS);
            }
            //按月开票
            if (StringUtils.isNotBlank(bo.getTimes ())){
                log.info ("前台传的times--------------------------" + bo.getTimes ());
                List<ShopSysInvoiceDTO> shopSysInvoiceDTOS = new ArrayList<>();
                String[] split = bo.getTimes ().split (",");
                for (String time :split) {
                    try {
                        Date date1 = new SimpleDateFormat ("yyyy-MM").parse(bo.getTimes ());
                        log.info ("时间格式1-----------------" + date1);
                        Date date = new SimpleDateFormat ("yyyy-MM").parse(time);
                        log.info ("时间格式2-----------------" + date);
                        List<ShopSysInvoiceVO>shopSysInvoiceVOS = shopSysInvoiceService.selectByMonth(date,bo.getShopId (),bo.getPriceType (),bo.getSellOrBuyType ());
                        for (ShopSysInvoiceVO vo: shopSysInvoiceVOS) {
                            ShopSysInvoiceDTO shopSysInvoiceDTO = new ShopSysInvoiceDTO ();
                            shopSysInvoiceDTO.setId (vo.getId ());
                            shopSysInvoiceDTO.setSysInvoiceId (sysInvoiceDTO.getId ()); //平台开票表id
                            shopSysInvoiceDTO.setStatus (0); //开票状态 0已开票，1未开票
                            shopSysInvoiceDTOS.add (shopSysInvoiceDTO);
                        }
                    } catch (ParseException e) {
                        log.info ("时间格式有误==================" + e );
                    }
                }
                updateFlag = shopSysInvoiceService.updateBatchById (shopSysInvoiceDTOS);
            }

        }
        return updateFlag;
    }

    /**
     * 平台开票
     * @param saveBO
     * @param sessionId
     * @param source
     * @return
     */
    @Override
    public boolean updateSysInvoice(SysInvoiceSaveBO saveBO, String sessionId, String source) {
        SysUserDTO sysUserDTO = (SysUserDTO) redisUtil.getSession(sessionId, source);
        SysInvoiceDTO dto = new SysInvoiceDTO();
        dto.setId (saveBO.getId ());
        dto.setUpdateUserId (sysUserDTO.getId ());  //更新人id
        dto.setInvoiceUrl (saveBO.getInvoiceUrl ());    //发票图片
        dto.setInvoiceCode (saveBO.getInvoiceCode ());  //发票代码
        dto.setInvoiceNumber (saveBO.getInvoiceNumber ());  //发票编号
        dto.setLogisticsType (saveBO.getLogisticsType ());  //物流类型,0选择物流,1自己联系物流
        dto.setCompanyName (saveBO.getCompanyName ());  //物流公司名称/送货员姓名
        dto.setNumberPhone (saveBO.getNumberPhone ());  //物流单号/送货员联系电话
        dto.setStatus (1);   //发票状态 0申请开票中，1开票成功
        dto.setUpdateTime (new Date ());   //更新时间
        Integer flag = baseMapper.updateById (dto);
        //发送邮件
        SysInvoiceDTO dto1 = baseMapper.selectById (saveBO.getId ());
        if (StringUtils.isNotBlank(dto1.getEmail()) && StringUtils.isNotBlank(saveBO.getInvoiceUrl ())) {
            this.sendEmail(dto1.getShopId (), dto1.getEmail(), saveBO.getInvoiceUrl());
        }

        return flag > 0 ;
    }

    @Override
    public boolean updateSysInvoiceById(SysInvoiceDTO sysInvoiceDTO) {
        log.info("-----------------sysInvoiceDTO="+sysInvoiceDTO.toString());
       boolean flag= this.updateById(sysInvoiceDTO);
       if (flag){
           SysInvoiceDTO sysInvoiceDTO1 = this.selectById(sysInvoiceDTO.getId());
           if (sysInvoiceDTO1.getInvoiceType()==1){
               this.sendEmail(sysInvoiceDTO1.getShopId (), sysInvoiceDTO1.getEmail(), sysInvoiceDTO1.getInvoiceUrl());
           }
       }
        return flag;
    }


    /**
     * 平台开票列表和店铺开票记录
     * @param bo
     * @return
     */
    @Override
    public Page<SysInvoiceVO> queryPageList(SysInvoiceQueryBO bo) {
        Page<SysInvoiceVO> page = new Page<>(bo.getPageNo(), bo.getPageSize());
        log.info("bo======================================"+bo.toString());
        List<SysInvoiceVO> vos = baseMapper.queryPageList(page, bo);
        page.setRecords(vos);
        return page;
    }

    @Async
    public void sendEmail(Long shopId, String email, String file) {
        EmailSendBO emailBO = new EmailSendBO();
        emailBO.setShopId(shopId);
        emailBO.setEmail(email);
        emailBO.setType(0);
        emailBO.setContext(file);
        emailInfoService.sendInvoiceEmail(emailBO);
    }

}
